/*
 * NetworkTests.cpp
 *
 *  Created on: 09.08.2011
 *      Author: Blinov Kirill
 *      Copyright: LGPL
 */

#include <boost/thread/thread.hpp>
#include <vector>
#include <iostream>
#include <string>

#include "CNetworkManager.h"

const UINT TEST_FIRST_PORT  = 8080;
const UINT TEST_SECOND_PORT = 8100;

const char TEST_SELF_IP_ADDRESS[] = "127.0.0.1";

CNetworkManager NetworkManager;

void
PrintMessageArray( std::vector<STANDART_NETWORK_MESSAGE*> TestMessageArray )
{
	for ( UINT i = 0; i < TestMessageArray.size(); i++ )
		{
		    NETWORK_MESSAGE_HEADER Header = TestMessageArray[i]->header;
			fprintf( stderr, "  _%u  size: %u, version: %u, group: %u, value: %u, clientId: %u, additionalData1: %u, additionalData2: %u \n",
					i, Header.size, Header.version, Header.group, Header.value, Header.clientId, Header.additionalData1,
					Header.additionalData2 );
			if ( ( Header.size > 0 ) && ( NULL != TestMessageArray[i]->data ) )
			{
				fprintf( stderr, "  _%u DATA: %s\n", i, TestMessageArray[i]->data );
			}
			if ( ( NET_MESSAGE_GROUP_ACTION == Header.group ) &&
				 ( NET_MESSAGE_ACTION_REJECTION == Header.value ) )
			{
				NetworkManager.BreakConnection( Header.clientId, false );
			}
			delete TestMessageArray[i];
		}
}

void
PrintTestResult( const bool Result, const UINT TestNumber )
{
	std::cout << "  Test " << TestNumber << (( Result ) ? " passed" : " failed" ) << "\n";
}

void
AskForPrintResult( const UINT TestNumber )
{
	std::cout << " Enter a number to recive messages\n";
	std::cin >> RandNumber;
	std::vector<STANDART_NETWORK_MESSAGE*> *TestMessageArray;
	TestMessageArray = NetworkManager.GetMessages();
	std::cout << "  Result messages: \n";
	PrintMessageArray( *TestMessageArray );
	PrintTestResult( ( TestMessageArray->size() > 0 ), TestNumber );
	delete TestMessageArray;
}

int main()
{
	std::cout << "Server/Client\n";
	std::cin >> RandNumber;

	std::cout << "START TESTS\n";

	std::vector<STANDART_NETWORK_MESSAGE*> TestMessageArray;

//--------------1 Test ( connection ) -----------------

	std::cout << " 1 START TEST ";
	if ( 0 == RandNumber )
	{
		std::cout << "- SERVER/n";
		NetworkManager.CreateConnection( TEST_FIRST_PORT, TEST_FIRST_PORT, 10 );
		boost::this_thread::sleep( boost::posix_time::milliseconds( 200 ) );
		std::cout << "  Server is created \n";
	}
	else
	{
		std::cout << "- CLIENT/n";
		NetworkManager.CreateConnection( TEST_SELF_IP_ADDRESS, TEST_FIRST_PORT, TEST_FIRST_PORT );
		boost::this_thread::sleep( boost::posix_time::milliseconds( 1000 ) );
		std::cout << "  Client is created \n";
	}
	std::cout << " NetworkManager 0 & 1 created\n";

	AskForPrintResult( 1 );

//--------------1 Test end -----------------

//--------------2 Test ( Send a simple messages ) -----------------

	std::cout << " Enter an Id of client to send test messages\n";
	std::cin >> RandNumber;
	STANDART_NETWORK_MESSAGE* Message1 = new STANDART_NETWORK_MESSAGE( NETWORK_PROTOCOL_VERSION, NET_MESSAGE_GROUP_ACTION,
																	   NET_MESSAGE_ACTION_GREETING, RandNumber );
	Message1->header.additionalData1 = NET_MESSAGE_ADD_INITIAL_GREETING;
	TestMessageArray.push_back( Message1 );

	STANDART_NETWORK_MESSAGE* Message2 = new STANDART_NETWORK_MESSAGE(  NETWORK_PROTOCOL_VERSION, NET_MESSAGE_GROUP_ACTION,
																		NET_MESSAGE_ACTION_REQUEST, RandNumber );
	Message2->header.additionalData1 = NET_MESSAGE_ADD_CHECK_CONNECTION;
	TestMessageArray.push_back( Message2 );

	NetworkManager.SendMessages( TestMessageArray );
	TestMessageArray.clear();

	AskForPrintResult( 2 );

//--------------2 Test end -----------------

//--------------3 Test ( Send message with data block ) -----------------

	std::cout << " Enter an Id of client to send message with body \n";
	std::cin >> RandNumber;

	char *TextMessage = new char[50];
	sprintf( TextMessage, "%s", "It's a simple Text message" );
	STANDART_NETWORK_MESSAGE* Message3 = new STANDART_NETWORK_MESSAGE( NETWORK_PROTOCOL_VERSION, NET_MESSAGE_GROUP_ACTION,
																	   NET_MESSAGE_ACTION_GREETING, RandNumber, (BYTE*)(TextMessage),
																	   sizeof(char) * 50 );
	Message3->header.additionalData1 = NET_MESSAGE_ADD_INITIAL_GREETING;

	TestMessageArray.push_back( Message3 );

	NetworkManager.SendMessages( TestMessageArray );

	TestMessageArray.clear();
	AskForPrintResult( 3 );

//--------------3 Test end -----------------

//--------------4 Test ( Disconnect ) -----------------

	std::cout << " Enter an Id of client to disconnect \n";
	std::cin >> RandNumber;

	NetworkManager.BreakConnection( RandNumber, true );

	AskForPrintResult( 4 );

//--------------4 Test end -----------------

	std::cout << " Enter an Id of client to send check connect message\n";
	std::cin >> RandNumber;


	std::cout << "TESTS ARE SUCCESSFULLY FINISHED!\n";
	std::cout << "Write smt\n";

	int State;
	std::cin >> State;

	return 0;
}
